home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 15093 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  2.8 KB

  1. Path: svnews.ubinet.ubs.com!ubszh!ubszh!gzhjis
  2. From: gzhjis@ubszh.net.ch (Ian Johnston (by ubsswop))
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Multiple Inheritance Pointer Problem
  5. Date: 3 Apr 1996 16:22:46 GMT
  6. Organization: UBS
  7. Distribution: world
  8. Message-ID: <4ju8km$ffv@ubszh.fh.zh.ubs.com>
  9. References: <31622A26.3633@nmaa.org>
  10. NNTP-Posting-Host: nol2179.fh.zh.ubs.com
  11.  
  12. In article <31622A26.3633@nmaa.org>, Uncle Snuggles <jphelps@nmaa.org> writes:
  13.  
  14. [About this pointers in a (non-virtual) multiple inheritance lattice]
  15.  
  16. No, this is not a compiler bug.
  17.  
  18. What follows is a general description; individual compilers may do things
  19. in slightly different ways, but the overall effects are the same.
  20.  
  21. The compiler lays out the data members of classes next to each other
  22. in memory. So (given your example with data members):
  23.  
  24.  
  25.     class foobar : public foo, public bar
  26.         foo::        (no data)
  27.         bar::        int b
  28.         foobar::    int fb
  29.  
  30. As the foo sub-object is the first sub-object in foobar (and there are
  31. no virtual functions, and no virtual inheritance), its address is always
  32. the same as the address of the foobar object.
  33.  
  34. Try printing out the address of the bar sub-object and see what happens.
  35.  
  36.  
  37.     class barfoo : public bar, public foo
  38.         bar::        int b
  39.         foo::        (no data)
  40.         barfoo::    int bf
  41.  
  42. Here, the address of the bar sub-object within barfoo is the same as the
  43. address of the barfoo object. The address of the foo sub-object within
  44. barfoo is 4 bytes after the start: that is, the size of an int.
  45.  
  46. When you call foo::PrintMe(), the this pointer must obviously point to
  47. a foo object.
  48.  
  49. In the first case, &foo == &foobar, so the this pointers are the same.
  50.  
  51. In the second case, &foo is 4 bytes after &barfoo (to allow for the
  52. int bar::b). So the compiler adds 4 to the this pointer to have it
  53. pointing to the foo sub-object in barfoo. This is the 4 byte difference
  54. you see.
  55.  
  56. In the 16-bit version, the 2 byte difference you see is the size of the
  57. int: now it is 2 bytes (its not the size of the pointer; check this
  58. by trying your example compiled with far pointers).
  59.  
  60.  
  61. Now take the example without data members.
  62.  
  63. When you allocate an object on the heap, the address of each object must
  64. be distinct. The easiest way to do this is to pretend that an empty class
  65. has a size of 1.
  66.  
  67. So now you have:
  68.  
  69.  
  70.     class foobar : public foo, public bar
  71.         foo::        (no data)
  72.         bar::        (no data)
  73.         foobar::    (no data)
  74.  
  75. The foo sub-object within the object is still at the same address as the
  76. entire foobar object, so the this pointers are the same.
  77.  
  78.  
  79.     class barfoo : public bar, public foo
  80.         bar::        (no data)
  81.         foo::        (no data)
  82.         barfoo::    (no data)
  83.  
  84. Here the bar sub-object is at the same address as the barfoo object. But the
  85. foo sub-object is after the bar sub-object. As the bar sub-object effectively
  86. has a size of 1, &foo is 1 byte after &barfoo. So the compiler adjusts
  87. the this pointer by 1 in the call to foo::PrintMe().
  88.  
  89. I hope this was clear :-)
  90.  
  91. Ian
  92.  
  93.  
  94.